<?php

namespace App\services\v1;

use App\Common\RedisCache\FetchVideoListCache;
use App\Common\RedisCache\UserCache;
use App\Jobs\user\RegisterToSms;
use App\Models\User;
use App\Models\UserMoneyCouponRecord;
use App\services\BaseServices;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Queue;

class UserServices extends BaseServices
{
    private $userCache;
    private $limitRequest;
    private $limitTime;

    public function __construct()
    {
        parent::__construct();
        $this->userCache = new UserCache();
        $this->limitRequest = 10;
        $this->limitTime = 60;
    }

    /**
     * 处理注册用户
     * @param string $userMobile
     * @param string $userEmail
     */
    public function setUser(string $userMobile, string $userEmail)
    {
        $formatData = [
            'user_mobile' => ($userMobile),
            'user_email'  => ($userEmail),
            'password'    => User::INIT_PASSWORD,
            'user_name'   => getChar(4),
        ];

        //注册成功给用户发email
        if (User::create($formatData)){
            Queue::push(new RegisterToSms($userEmail,$userMobile),'',RegisterToSms::QUEUE_NAME);
            return $this->resData;
        }
        $this->resData['code'] = 10006;
        return $this->resData;
    }

    /**
     * check user mobile or email is exists
     * @param string $mobile
     * @param string $userEmail
     * @return bool
     */
    public function getUserByMobile(string $mobile, string $userEmail)
    {
        return User::query()->where('user_mobile',$mobile)->first() || User::query()->where('user_email',$userEmail)->first();
    }

    /**
     * @param int $userId
     * @return array
     */
    public function getUserInfoById(int $userId): array
    {
        $user = User::find($userId);
        if (!$user) return [];
        return $user->toArray();
    }

    /**
     * 限制用户请求 incr方式
     * @return int|string
     */
    public function limitCounterByString()
    {
        $this->userCache->setKeyParameter(['limitByString']);
        $counter = $this->userCache->get();
        if ($counter > $this->limitRequest) {
            return 'limit of ten, please sometimes come here!';
        }
        if (!$counter) {
            $this->userCache->set(0, $this->limitTime);
        }
        $this->userCache->increase();
        return $counter;
    }

    /**
     * 限制用户请求 list方式
     * @return int|string
     */
    public function limitCounterByList()
    {
        $list = new FetchVideoListCache();
        $list::$json = false;
        $list->setKeyParameter(['limitByList']);
        $counter = $list->len();
        $time = time();
        if ($counter > $this->limitRequest) {
            $oldNode = $list->lindex('', -1);
            if ($time - $oldNode < $this->limitTime) {
                return 'limit of ten, please sometimes come here!';
            }
            $list->lPush($time);
            $list->ltrim('', 0, $this->limitRequest - 1);
        }
        if ($counter <= $this->limitRequest) {
            $list->lPush($time);
        }
        return $counter;
    }

    /**
     * 给指定用户生成现金券
     * @param int $userId
     * @return Builder|Model
     */
    public function sendMoneyCouponToUsers(int $userId = 0, string $userName = '名字')
    {
        //generate money coupon of ten length
        $couponCodeExits = true;
        while ($couponCodeExits) {
            $couponCode = createRandString(15);
            $couponCodeExits = UserMoneyCouponRecord::query()->where(['coupon_code' => $couponCode])->exists();
        }
        $dateTime = date('Y-m-d H:i:s');
        $insertData = [
            "coupon_name" => $userName,
            "coupon_code" => $couponCode,
            "user_id" => $userId,
            "start_time" => $dateTime,
            "end_time" => $dateTime,
        ];
        return UserMoneyCouponRecord::query()->create($insertData);
    }

    /**
     * 核销单个用户现金券
     * @param int $userId
     * @param string $couponCode
     * @return bool
     */
    public function useMoneyCoupon(int $userId, string $couponCode)
    {
        //校验现金券
        $couponCodeExits = UserMoneyCouponRecord::query()
            ->where(['coupon_code' => $couponCode, 'state' => UserMoneyCouponRecord::STATE_UNUSED]);
        if (!$couponCodeExits->exists()) {
            return false;
        }
        return (bool)$couponCodeExits->update(['state' => UserMoneyCouponRecord::STATE_USED]);
    }

}